/**
 *
 */
package com.engine.grm;

import java.util.Date;
import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.criterion.Restrictions;

import com.se.grm.client.mapping.GrmRequest;
import com.se.grm.client.mapping.GrmRequestCategory;
import com.se.grm.client.mapping.GrmRequestStatusHistory;
import com.se.grm.client.mapping.GrmRequestStaus;
import com.se.grm.client.mapping.GrmUser;
import com.util.EngineUtil;
import com.wfe.db.SessionUtil;
import com.wfe.db.WorkFlowEngineQueryUtil;
import com.wfe.mapping.client.Request;
import com.wfe.mapping.client.RequestConf;
import com.wfe.mapping.client.WfProjectTaskStatus;

/**
 * @author kareem_yehya
 * @since 22 October 2010
 * @version 2.0.0.1
 * 
 *          This Calss Responsible for the Following <br>
 *          1. Collect Requests for Request handeler <br>
 *          2. Change the status of the requests to be in process by WFE
 * @see com.engine.grm.RequestExecuter <br>
 *      For how the Requests executed
 */
public class RequestCollector implements Runnable
{

	private static List<RequestConf> requestConfList;

	public RequestCollector()
	{
		setRequestConfList(getRequestConfList());

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see java.lang.Runnable#run()
	 */
	public void run()
	{
		while(true)
		{
			try
			{
				System.out.println("Enter Request Collector Main Thread");
				if(requestConfList.size() > 0)
				{
					for(RequestConf requestConf : requestConfList)
					{
						GrmRequestCategory grmRequestCategory = getGrmRequestCategory(requestConf.getRequestTypeId().longValue());
						List<GrmRequest> grmRequestList = getGrmRequestList(100, grmRequestCategory, "Approved");
						if(grmRequestList != null && grmRequestList.size() > 0)
						{
							for(GrmRequest grmRequest : grmRequestList)
							{
								boolean isExecuted = collectRequest(grmRequest, requestConf);
								if(isExecuted)
								{
									System.out.println("Request collected Id = " + grmRequest.getId());
									boolean isStatusChanged = changeRequestStatusOnGRM(grmRequest);
									if(isStatusChanged)
									{
										System.out.println("Request Status changed  Id = " + grmRequest.getId());
									}
								}
							}
						}
						else
						{

							System.out.println("No Any new approved requests with this category " + grmRequestCategory.getName());

						}

						Thread.sleep(5000);// Sleep After Every category
					}// for end

				}
				else
				{
					System.out.println("No Any new request Configurations");
				}

			}catch(Exception e)
			{
				e.printStackTrace();
			}
		}

	}

	private boolean collectRequest(GrmRequest grmRequest, RequestConf requestConf)
	{
		// 1- Add request to WFE

		Request request = null;
		Session session = null;
		try
		{
			session = SessionUtil.getSession();
			WfProjectTaskStatus wfProjectTaskStatus = getWfProjectTaskStatusByID(5l);
			WorkFlowEngineQueryUtil.getRandomID();
			request = new Request(WorkFlowEngineQueryUtil.getRandomID(), wfProjectTaskStatus, grmRequest.getId(), new Date(), null, requestConf);
			session.save(request);
			session.beginTransaction().commit();
			System.out.println("New Request has been Added RequestID = " + grmRequest.getId() + " Recid = " + request.getRecid());
			return true;
		}catch(Exception e)
		{
			e.printStackTrace();
			return false;
		}finally
		{
			EngineUtil.closeSession(session);

		}

	}

	/**
	 * 
	 * @author kareem_yehya
	 * 
	 * @since 23 October 2010
	 * 
	 * 
	 * */

	private boolean changeRequestStatusOnGRM(GrmRequest grmRequest)
	{

		// 1- change it is status to WFE_Inprogress by adding record to history
		GrmRequestStatusHistory grmRequestStatusHistory = null;
		GrmRequestStaus grmRequestStaus = null;
		GrmUser grmUser = null;
		Session session2 = null;
		try
		{
			grmRequestStaus = getGrmRequestStaus(13l);// WFE_Inprogress
			grmUser = getGrmUser(999999999l);// / WFE User
			grmRequestStatusHistory = new GrmRequestStatusHistory(WorkFlowEngineQueryUtil.getRandomID(), grmUser, grmRequestStaus, grmRequest, new Date());
			session2 = com.se.grm.db.SessionUtil.getSession();
			session2.save(grmRequestStatusHistory);
			System.out.println("New Request History record has been Added RequestID = " + grmRequest.getId());
			return true;
		}catch(Exception e)
		{
			e.printStackTrace();
			return false;
		}finally
		{
			if(session2 != null)
				session2.close();

		}

	}

	@SuppressWarnings("unchecked")
	private List<GrmRequest> getGrmRequestList(int i, GrmRequestCategory grmRequestCategory, String status)
	{
		Session session2 = null;
		List<GrmRequest> retList = null;
		try
		{
			session2 = com.se.grm.db.SessionUtil.getSession();
			Criteria criteria = session2.createCriteria(GrmRequest.class);
			criteria.add(Restrictions.eq("grmRequestCategory", grmRequestCategory));
			criteria.add(Restrictions.eq("lastStatus", status));
			retList = criteria.list();

			return retList;
		}catch(Exception e)
		{
			e.printStackTrace();
			return null;
		}finally
		{
			if(session2 != null)
				session2.close();
		}
	}

	/**
	 * @author kareem_yehya
	 * @since 23 October 2010
	 * @param categoryID
	 *            = Request Category ID
	 * 
	 * */

	private GrmRequestCategory getGrmRequestCategory(long categoryID)
	{
		Session session2 = null;
		GrmRequestCategory grmRequestCategory = null;
		try
		{
			session2 = com.se.grm.db.SessionUtil.getSession();
			Criteria criteria = session2.createCriteria(GrmRequestCategory.class);
			criteria.add(Restrictions.eq("id", categoryID));
			grmRequestCategory = (GrmRequestCategory) criteria.uniqueResult();
			return grmRequestCategory;
		}catch(Exception e)
		{
			e.printStackTrace();
			return null;
		}finally
		{
			if(session2 != null)
				session2.close();
		}
	}

	/**
	 * @author kareem_yehya
	 * @since 24 October 2010
	 * */

	private GrmUser getGrmUser(long ID)
	{
		Session session2 = null;
		GrmUser grmUser = null;
		try
		{
			session2 = com.se.grm.db.SessionUtil.getSession();
			Criteria criteria = session2.createCriteria(GrmUser.class);
			criteria.add(Restrictions.eq("id", ID));
			grmUser = (GrmUser) criteria.uniqueResult();
			return grmUser;
		}catch(Exception e)
		{
			e.printStackTrace();
			return null;
		}finally
		{
			if(session2 != null)
				session2.close();
		}
	}

	/**
	 * @author kareem_yehya
	 * @since 24 October 2010
	 * */

	private GrmRequestStaus getGrmRequestStaus(long status_ID)
	{
		Session session2 = null;
		GrmRequestStaus grmRequestStaus = null;
		try
		{
			session2 = com.se.grm.db.SessionUtil.getSession();
			Criteria criteria = session2.createCriteria(GrmRequestStaus.class);
			criteria.add(Restrictions.eq("id", status_ID));
			grmRequestStaus = (GrmRequestStaus) criteria.uniqueResult();
			return grmRequestStaus;
		}catch(Exception e)
		{
			e.printStackTrace();
			return null;
		}finally
		{
			if(session2 != null)
				session2.close();
		}
	}

	/**
	 * @author kareem_yehya
	 * @since 23 October 2010
	 * 
	 * 
	 * 
	 * */

	@SuppressWarnings("unchecked")
	private static List<RequestConf> getRequestConfList()
	{
		Session session = null;
		List<RequestConf> retList = null;
		try
		{
			session = SessionUtil.getSession();
			Criteria criteria = session.createCriteria(RequestConf.class);
			retList = criteria.list();
			return retList;

		}catch(Exception e)
		{
			e.printStackTrace();
			return null;
		}finally
		{
			EngineUtil.closeSession(session);
		}
	}

	public static void setRequestConfList(List<RequestConf> requestConfList)
	{
		RequestCollector.requestConfList = requestConfList;
	}

	/**
	 * @author kareem_yehya
	 * @since 24 October 2010
	 * 
	 * 
	 * */
	public static WfProjectTaskStatus getWfProjectTaskStatusByID(long i)
	{

		Session session = null;
		try
		{
			session = SessionUtil.getSession();
			Criteria criteria = session.createCriteria(WfProjectTaskStatus.class);
			criteria.add(Restrictions.eq("recid", i));
			return (WfProjectTaskStatus) criteria.uniqueResult();

		}catch(Exception e)
		{
			e.printStackTrace();
			return null;
		}finally
		{
			EngineUtil.closeSession(session);
		}

	}

	public static void main(String args[])
	{
		//
		// Session session2 = com.se.grm.db.SessionUtil.getSession();
		// GrmRequest r = (GrmRequest) session2.get(GrmRequest.class, 1l);
		// System.out.println(r);
		//
		// Session session = SessionUtil.getSession();
		// Request rr = (Request) session.get(Request.class, 1l);
		// System.out.println(rr);

		(new Thread(new RequestCollector())).start();
	}
}
